﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Kang.ExtendMethod
{
    public enum SubstringPlaceholderMode
    {
        Left = 1,
        Right = 2
    }

    public static class StringExtendMethod
    {
        /// <summary>
        /// 安全方法，获取字符串的Trim()结果
        /// </summary>
        /// <param name="str">待Trim的字符串</param>
        /// <returns>Trim后的字符串</returns>
        public static string StringTrim(this string str)
        {
            if (IsBlank(str))
            {
                return default;
            }
            return str.Trim();
        }

        /// <summary>
        /// 字符串转Guid类型，字符串为空或转换失败时，返回NULL
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static Guid? ToGuid(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            Guid _v = Guid.Empty;
            if (Guid.TryParse(str, out _v))
            {
                return _v;
            }
            return null;
        }

        /// <summary>
        /// 安全方法，字符串转Int类型
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static int ToInteger(this string str)
        {
            int _v = 0;
            if (int.TryParse(str, out _v))
            {
                return _v;
            }
            return default;
        }

        /// <summary>
        /// 安全方法，字符串转Long类型
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static long ToLong(this string str)
        {
            long _v = 0;
            if (long.TryParse(str, out _v))
            {
                return _v;
            }
            return default;
        }

        /// <summary>
        /// 安全方法，字符串转Float类型
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static float ToFloat(this string str)
        {
            float _v = 0;
            if (float.TryParse(str, out _v))
            {
                return _v;
            }
            return default;
        }

        /// <summary>
        /// 安全方法，字符串转Double类型
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static double ToDouble(this string str)
        {
            double _v = 0;
            if (double.TryParse(str, out _v))
            {
                return _v;
            }
            return default;
        }

        /// <summary>
        /// 安全方法，字符串转Decimal类型
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static decimal ToDecimal(this string str)
        {
            decimal _v = 0;
            if (decimal.TryParse(str, out _v))
            {
                return _v;
            }
            return default;
        }

        /// <summary>
        /// 字符串转DateTime类型，字符串为空或转换失败时，返回NULL
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static DateTime? ToDateTime(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            DateTime _v;
            if (DateTime.TryParse(str, out _v))
            {
                return _v;
            }
            return null;
        }

        /// <summary>
        /// 字符串转DateTime类型，字符串为空或转换失败时，返回NULL
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static DateTime? ToDateTime(this string str, string format)
        {
            if (IsBlank(str) || IsBlank(format))
            {
                return null;
            }
            DateTime _v;
            if (DateTime.TryParseExact(str, format, System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None, out _v))
            {
                return _v;
            }
            return null;
        }

        /// <summary>
        /// 安全方法，字符串转bool类型，【0、false字符串、空字符串】返回False，【非0、非空字符串】返回True
        /// </summary>
        /// <param name="str">待转换的字符串</param>
        /// <returns>转换后的对象</returns>
        public static bool ToBool(this string str)
        {
            if (IsNotNumber(str))
            {
                if (IsBlank(str) || "false".Equals(StringTrim(str).ToLower()))
                {
                    return false;
                }
                return true;
            }
            var _v = ToInteger(str);
            if (_v == 0)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 字符串转根据英文逗号分割，转int数组，非int字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <returns>分割转换后的结果</returns>
        public static int[] ToIntegerArray(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<int>();
            var n_arr = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToInteger(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitChar分割，转int数组，非int字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitChar">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static int[] ToIntegerArray(this string str, char splitChar)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<int>();
            var n_arr = str.Split(new char[] { splitChar }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToInteger(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitStr分割，转int数组，非int字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitStr">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static int[] ToIntegerArray(this string str, string splitStr)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<int>();
            var n_arr = str.Split(new string[] { splitStr }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToInteger(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据英文逗号分割，转long数组，非long字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <returns>分割转换后的结果</returns>
        public static long[] ToLongArray(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<long>();
            var n_arr = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToLong(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitChar分割，转long数组，非long字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitChar">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static long[] ToLongArray(this string str, char splitChar)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<long>();
            var n_arr = str.Split(new char[] { splitChar }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToLong(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitStr分割，转long数组，非long字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitStr">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static long[] ToLongArray(this string str, string splitStr)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<long>();
            var n_arr = str.Split(new string[] { splitStr }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToLong(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据英文逗号分割，转float数组，非float字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <returns>分割转换后的结果</returns>
        public static float[] ToFloatArray(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<float>();
            var n_arr = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToFloat(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitChar分割，转float数组，非float字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitChar">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static float[] ToFloatArray(this string str, char splitChar)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<float>();
            var n_arr = str.Split(new char[] { splitChar }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToFloat(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitStr分割，转float数组，非float字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitStr">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static float[] ToFloatArray(this string str, string splitStr)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<float>();
            var n_arr = str.Split(new string[] { splitStr }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToFloat(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据英文逗号分割，转double数组，非double字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <returns>分割转换后的结果</returns>
        public static double[] ToDoubleArray(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<double>();
            var n_arr = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToDouble(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitChar分割，转double数组，非double字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitChar">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static double[] ToDoubleArray(this string str, char splitChar)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<double>();
            var n_arr = str.Split(new char[] { splitChar }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToDouble(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitStr分割，转double数组，非double字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitStr">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static double[] ToDoubleArray(this string str, string splitStr)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<double>();
            var n_arr = str.Split(new string[] { splitStr }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToDouble(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据英文逗号分割，转decimal数组，非decimal字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <returns>分割转换后的结果</returns>
        public static decimal[] ToDecimalArray(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<decimal>();
            var n_arr = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToDecimal(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitChar分割，转decimal数组，非decimal字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitChar">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static decimal[] ToDecimalArray(this string str, char splitChar)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<decimal>();
            var n_arr = str.Split(new char[] { splitChar }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToDecimal(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitStr分割，转decimal数组，非decimal字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitStr">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static decimal[] ToDecimalArray(this string str, string splitStr)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<decimal>();
            var n_arr = str.Split(new string[] { splitStr }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                if (IsNumber(_v))
                {
                    list.Add(ToDecimal(_v));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据英文逗号分割，转bool数组，非bool字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <returns>分割转换后的结果</returns>
        public static bool[] ToBoolArray(this string str)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<bool>();
            var n_arr = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var _v in n_arr)
            {
                list.Add(ToBool(_v));
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitChar分割，转bool数组，非bool字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitChar">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static bool[] ToBoolArray(this string str, char splitChar)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<bool>();
            var n_arr = str.Split(new char[] { splitChar }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                list.Add(ToBool(_v));
            }
            return list.ToArray();
        }

        /// <summary>
        /// 字符串转根据splitStr分割，转bool数组，非bool字符串会被过滤
        /// </summary>
        /// <param name="str">待分割转换的字符串</param>
        /// <param name="splitStr">分割符</param>
        /// <returns>分割转换后的结果</returns>
        public static bool[] ToBoolArray(this string str, string splitStr)
        {
            if (IsBlank(str))
            {
                return null;
            }
            var list = new List<bool>();
            var n_arr = str.Split(new string[] { splitStr }, StringSplitOptions.RemoveEmptyEntries);
            if (IsBlank(n_arr))
            {
                return null;
            }
            foreach (var _v in n_arr)
            {
                list.Add(ToBool(_v));
            }
            return list.ToArray();
        }

        /// <summary>
        /// 判断字符串是否为空字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <returns>是否为空字符串，判断结果</returns>
        public static bool IsBlank(this string str)
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                return true;
            }
            if (string.IsNullOrEmpty(str))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断字符串是否为空字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <param name="action">为空字符串时执行的方法</param>
        /// <param name="uaction">不为空字符串时执行的方法</param>
        public static void IsBlank(this string str, Action action, Action uaction = null)
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                action?.Invoke();
                return;
            }
            if (string.IsNullOrEmpty(str))
            {
                action?.Invoke();
                return;
            }
            uaction?.Invoke();
        }

        /// <summary>
        /// 判断字符串是否为空字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <param name="action">为空字符串时执行的方法</param>
        /// <param name="uaction">不为空字符串时执行的方法</param>
        public static void IsBlank(this string str, Action<char> action, Action<char> uaction = null)
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                foreach (char o in str)
                {
                    action?.Invoke(o);
                }
                return;
            }
            if (string.IsNullOrEmpty(str))
            {
                foreach (char o in str)
                {
                    action?.Invoke(o);
                }
                return;
            }
            foreach (char o in str)
            {
                uaction?.Invoke(o);
            }
        }

        /// <summary>
        /// 判断字符串是否不为空字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <returns>是否不为空字符串，判断结果</returns>
        public static bool IsNotBlank(this string str)
        {
            return !IsBlank(str);
        }

        /// <summary>
        /// 判断字符串是否不为空字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <param name="action">不为空字符串时执行的方法</param>
        /// <param name="uaction">为空字符串时执行的方法</param>
        public static void IsNotBlank(this string str, Action action, Action uaction = null)
        {
            if (IsBlank(str))
            {
                uaction?.Invoke();
                return;
            }
            action?.Invoke();
        }

        /// <summary>
        /// 判断字符串是否不为空字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <param name="action">不为空字符串时执行的方法</param>
        /// <param name="uaction">为空字符串时执行的方法</param>
        public static void IsNotBlank(this string str, Action<char> action, Action<char> uaction = null)
        {
            if (IsBlank(str))
            {
                foreach (char o in str)
                {
                    uaction?.Invoke(o);
                }
                return;
            }
            foreach (char o in str)
            {
                action?.Invoke(o);
            }
        }

        /// <summary>
        /// 返回指定路径地址的目录信息
        /// </summary>
        /// <param name="str">Path字符串</param>
        /// <returns>目录地址</returns>
        public static string GetDirectoryName(this string str)
        {
            return Path.GetDirectoryName(str);
        }

        /// <summary>
        /// 正则表达式替换字符串
        /// </summary>
        /// <param name="str">字符串内容</param>
        /// <param name="pattern">替换字符</param>
        /// <param name="replaceStr">替换值</param>
        /// <returns>替换后的字符串</returns>
        public static string RegexReplace(this string str, string pattern, string replaceStr)
        {
            if (IsBlank(str))
            {
                return default;
            }
            return Regex.Replace(str, pattern, replaceStr);
        }

        /// <summary>
        /// 自定义正则匹配验证规则
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <param name="pattern">正则表达式</param>
        /// <returns>判断结果</returns>
        public static bool RegexIs(this string str, string pattern)
        {
            if (IsBlank(str))
            {
                return default;
            }
            return Regex.IsMatch(str, @pattern);
        }

        /// <summary>
        /// 是否[正数、负数]字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsNumber(this string str)
        {
            if (IsBlank(str))
            {
                return default;
            }
            return Regex.IsMatch(str.StringTrim(), @"^(\-|\+)?\d*$");
        }

        /// <summary>
        /// 是否非[正数、负数]字符串
        /// </summary>
        /// <param name="str">待判断的字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsNotNumber(this string str)
        {
            return !IsNumber(str);
        }

        /// <summary>
        /// 获取所有的，根据左右标签字符串，获取中间字符串
        /// </summary>
        /// <param name="strString"></param>
        /// <param name="left">左标签</param>
        /// <param name="right">右标签</param>
        /// <returns>返回左右标签中间的字符串内容</returns>
        public static string[] GetAllSubStringByLeftStringAndRightStrng(this string strString, string left, string right)
        {
            List<string> result = new List<string>();
            int leftIndex = -1;
            int rightIndex = -1;
            int i = 0, leftCount = 0, rightCount = 0, maxCount = 0;
            leftCount = Regex.Matches(strString, left).Count;
            rightCount = Regex.Matches(strString, right).Count;
            maxCount = leftCount > rightCount ? leftCount : rightCount;
            for (i = 0; i < maxCount; i++)
            {
                if (strString.Length < 2)
                {
                    break;
                }
                leftIndex = strString.IndexOf(left);
                // 如果左字符串为最后一个
                if (leftIndex + left.Length == strString.Length)
                {
                    break;
                }
                else
                {
                    // 去除左字符串，然后查找右字符串
                    rightIndex = strString.Substring(leftIndex + left.Length).IndexOf(right);
                }
                if (leftIndex < 0 || rightIndex < 0)
                {
                    break;
                }
                rightIndex = rightIndex + leftIndex + left.Length;
                result.Add(strString.Substring(leftIndex + left.Length, rightIndex - (leftIndex + left.Length)));
                if (strString.Length > rightIndex + right.Length)
                {
                    strString = strString.Substring(rightIndex + right.Length);
                }
                else
                {
                    break;
                }
            }
            return result.ToArray();
        }

        /// <summary>
        /// 替换字符串中所有出现过的子字符串
        /// </summary>
        /// <param name="str">待执行替换的字符串</param>
        /// <param name="oldString">需要被替换的字符串子串数组</param>
        /// <param name="newString">需要替换成的字符串子串数组</param>
        /// <returns>返回替换后的字符串</returns>
        public static string ReplaceAll(this string str, List<string> oldString, List<string> newString)
        {
            if (oldString.Count > 0 && newString.Count > 0 && oldString.Count == newString.Count)
            {
                for (int i = 0, count = oldString.Count; i < count; i++)
                {
                    str = str.Replace(oldString[i], newString[i]);
                }
            }
            return str;
        }

        /// <summary>
        /// 替换字符串中所有出现过的子字符串，后面两个数组参数的长度需要一致
        /// </summary>
        /// <param name="str">待执行替换的字符串</param>
        /// <param name="oldString">需要被替换的字符串子串数组</param>
        /// <param name="newString">需要替换成的字符串子串数组</param>
        /// <returns>返回替换后的字符串</returns>
        public static string ReplaceAll(this string str, string[] oldString, string[] newString)
        {
            if (oldString.Length > 0 && newString.Length > 0 && oldString.Length == newString.Length)
            {
                for (int i = 0, count = oldString.Length; i < count; i++)
                {
                    str = str.Replace(oldString[i], newString[i]);
                }
            }
            return str;
        }

        /// <summary>
        /// 计算MD5，32位
        /// </summary>
        /// <param name="str">待计算字符串</param>
        /// <returns>返回计算后的MD5值，32位</returns>
        public static string MD5Encrypt32(this string str)
        {
            if (IsBlank(str))
            {
                return default;
            }
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] bytes = Encoding.UTF8.GetBytes(str);
            bytes = md5.ComputeHash(bytes);
            md5.Clear();

            string ret = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
            }
            return ret.PadLeft(32, '0');
        }

        /// <summary>
        /// Base64加密，默认UTF8
        /// </summary>
        /// <param name="str">待加密字符串</param>
        /// <param name="encoding">字符串编码格式</param>
        /// <returns>返回加密后的字符串</returns>
        public static string ToBase64String(this string str, Encoding encoding = null)
        {
            if (IsBlank(str))
            {
                return default;
            }
            if (encoding == null)
            {
                return Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
            }
            return Convert.ToBase64String(encoding.GetBytes(str));
        }

        /// <summary>
        /// Base64解密，默认UTF8
        /// </summary>
        /// <param name="str">待解密字符串</param>
        /// <param name="encoding">字符串编码格式</param>
        /// <returns>返回解密后的字符串</returns>
        public static string Base64ToString(this string str, Encoding encoding = null)
        {
            if (IsBlank(str))
            {
                return default;
            }
            if (encoding == null)
            {
                return Encoding.UTF8.GetString(Convert.FromBase64String(str));
            }
            return encoding.GetString(Convert.FromBase64String(str));
        }

        /// <summary>
        /// Path.Combine的字符串扩展方法
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="paths">待拼接的字符串数组参数</param>
        /// <returns>路径拼接后的字符串</returns>
        public static string CombinePath(this string str, params string[] paths)
        {
            if (IsBlank(str))
            {
                return default;
            }
            if (IsBlank(paths))
            {
                return str;
            }
            var pathList = GetNotBlank(paths).ToList();
            pathList.Insert(0, str);
            return Path.Combine(pathList.ToArray());
        }

        /// <summary>
        /// 对Url进行类似Path.Combine的处理
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="paths">待拼接的字符串数组参数</param>
        /// <returns>Url拼接后的字符串</returns>
        public static string CombineUrl(this string str, params string[] paths)
        {
            if (IsBlank(str))
            {
                return default;
            }
            var start = str;
            var pathList = GetNotBlank(paths).ToList();
            foreach (var path in pathList)
            {
                if (path.StartsWith("/"))
                {
                    if (start.EndsWith("/"))
                    {
                        start = $"{start.Substring(0, start.Length - 1)}/{path.Substring(1)}";
                    }
                    else
                    {
                        start = $"{start}{path}";
                    }
                }
                else
                {
                    if (start.EndsWith("/"))
                    {
                        start = $"{start}{path}";
                    }
                    else
                    {
                        start = $"{start}/{path}";
                    }
                }
            }
            return start;
        }

        /// <summary>
        /// 判断字符串数组是否为空，全为空字符串的字符串数组也返回true
        /// </summary>
        /// <param name="strArr">字符串数组</param>
        /// <returns>是否为空，判断结果</returns>
        public static bool IsBlank(this string[] strArr)
        {
            if (strArr == null)
            {
                return true;
            }
            if (strArr.Length == 0)
            {
                return true;
            }
            foreach (var s in strArr)
            {
                if (s.IsNotBlank())
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 判断字符串数组是否不为空，有一个字符串不为空，则返回true
        /// </summary>
        /// <param name="strArr">字符串数组</param>
        /// <returns>是否不为空，判断结果</returns>
        public static bool IsNotBlank(this string[] strArr)
        {
            return !IsBlank(strArr);
        }

        /// <summary>
        /// 获取字符串数组中所有不为空的字符串，返回一个新的字符串数组
        /// </summary>
        /// <param name="strArr">字符串数组</param>
        /// <returns>所有不为空的字符串，组成的新数组</returns>
        public static string[] GetNotBlank(this string[] strArr)
        {
            if (IsBlank(strArr))
            {
                return default;
            }
            var list = new List<string>();
            foreach (var s in strArr)
            {
                if (IsNotBlank(s))
                {
                    list.Add(s);
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 获取字符串数组中所有不为空的字符串并进行Trim，返回一个新的字符串数组
        /// </summary>
        /// <param name="strArr">字符串数组</param>
        /// <returns>所有不为空的字符串调用Trim后，组成的新数组</returns>
        public static string[] GetNotBlankAndTrim(this string[] strArr)
        {
            if (IsBlank(strArr))
            {
                return default;
            }
            var list = new List<string>();
            foreach (var s in strArr)
            {
                if (IsNotBlank(s))
                {
                    list.Add(StringTrim(s));
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// 从左边截取字符串，默认左侧补位
        /// </summary>
        /// <param name="str">待截取的字符串</param>
        /// <param name="length">要截取的长度</param>
        /// <param name="placeholder">补位字符</param>
        /// <param name="placeholderMode">选择补位在截取后的字符串左边还是右边</param>
        /// <returns>左侧截取的字符串</returns>
        public static string Left(this string str, int length, char? placeholder = null, SubstringPlaceholderMode? placeholderMode = null)
        {
            if (IsBlank(str) || length == 0)
            {
                return default;
            }
            if (str.Length > length)
            {
                return str.Substring(0, length);
            }
            else if(placeholder != null && str.Length < length)
            {
                int i;
                var s = str;
                var c_count = length - str.Length;
                switch (placeholderMode)
                {
                    case null:
                    case SubstringPlaceholderMode.Left:
                        for (i = 0; i < c_count; i++)
                        {
                            s = $"{placeholder}{s}";
                        }
                        break;
                    case SubstringPlaceholderMode.Right:
                        for (i = 0; i < c_count; i++)
                        {
                            s = $"{s}{placeholder}";
                        }
                        break;
                }
                return s;
            }
            return str;
        }

        /// <summary>
        /// 从右边截取字符串，默认左侧补位
        /// </summary>
        /// <param name="str">待截取的字符串</param>
        /// <param name="length">要截取的长度</param>
        /// <param name="placeholder">补位字符</param>
        /// <param name="placeholderMode">选择补位在截取后的字符串左边还是右边</param>
        /// <returns>右侧截取的字符串</returns>
        public static string Right(this string str, int length, char? placeholder = null, SubstringPlaceholderMode? placeholderMode = null)
        {
            if (IsBlank(str) || length == 0)
            {
                return default;
            }
            if (str.Length > length)
            {
                var startIndex = str.Length - length;
                return str.Substring(startIndex);
            }
            else if(placeholder != null && str.Length < length)
            {
                int i;
                var s = str;
                var c_count = length - str.Length;
                switch (placeholderMode)
                {
                    case null:
                    case SubstringPlaceholderMode.Left:
                        for (i = 0; i < c_count; i++)
                        {
                            s = $"{placeholder}{s}";
                        }
                        break;
                    case SubstringPlaceholderMode.Right:
                        for (i = 0; i < c_count; i++)
                        {
                            s = $"{s}{placeholder}";
                        }
                        break;
                }
                return s;
            }
            return str;
        }

        /// <summary>
        /// 转为byte数组，默认UTF8
        /// </summary>
        /// <param name="str">待转换获取bytes的字符串</param>
        /// <param name="encoding">字符串编码格式</param>
        /// <returns>Bytes</returns>
        public static byte[] GetBytes(this string str, Encoding encoding = null)
        {
            if (IsBlank(str))
            {
                return null;
            }
            if (encoding == null)
            {
                return Encoding.UTF8.GetBytes(str);
            }
            return encoding.GetBytes(str);
        }

        /// <summary>
        /// Url编码，默认UTF8
        /// </summary>
        /// <param name="str">Url编码前的字符串</param>
        /// <param name="encoding">字符串编码格式</param>
        /// <returns>编码后的Url</returns>
        public static string UrlEncode(this string str, Encoding encoding = null)
        {
            if (encoding == null)
            {
                return HttpUtility.UrlEncode(str, Encoding.UTF8);
            }
            return HttpUtility.UrlEncode(str, encoding);
        }

        /// <summary>
        /// Url解码，默认UTF8
        /// </summary>
        /// <param name="str">Url编码后的字符串</param>
        /// <param name="encoding">字符串编码格式</param>
        /// <returns>解码后的Url</returns>
        public static string UrlDecode(this string str, Encoding encoding = null)
        {
            if (encoding == null)
            {
                return HttpUtility.UrlDecode(str, Encoding.UTF8);
            }
            return HttpUtility.UrlDecode(str, encoding);
        }

        /// <summary>
        /// 俗称：脱敏功能，替换指定字符串的指定区间内字符为"*"或其它指定字符
        /// </summary>
        /// <returns>脱敏字符串</returns>
        public static string Hide(this string str, int startIndex, int length = -1, char hideChar = '*')
        {
            StringBuilder newString;
            if (str.IsBlank())
            {
                return string.Empty;
            }
            if (startIndex >= str.Length || length <= 0)
            {
                return str;
            }
            newString = new StringBuilder();
            if (startIndex < 0)
            {
                startIndex = 0;
            }
            int strLength = str.Length;
            startIndex.For(i =>
            {
                newString.Append(str[i]);
            });
            int totalAppendLength = str.Length - startIndex;
            if (length < totalAppendLength)
            {
                length.For(i =>
                {
                    newString.Append(hideChar);
                });
                newString.Append(str.Substring(startIndex + length));
            }
            else
            {
                totalAppendLength.For(i =>
                {
                    newString.Append(hideChar);
                });
            }
            return newString.ToString();
        }
    }
}
